----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    22:04:45 01/20/2010 
-- Design Name: 
-- Module Name:    MemorySample - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- General package
use work.GeneralProperties.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity MemorySample is
  Port (
    CLK                  : in     STD_LOGIC;
	 MEM_Data             : out    STD_LOGIC_VECTOR ((bus_size-1) downto 0);
    MEM_DataIn           : in     STD_LOGIC_VECTOR ((bus_size-1) downto 0);
	 MEM_WriteAdd         : in     STD_LOGIC_VECTOR ((bus_size-1) downto 0);
	 MEM_ReadAdd          : in     STD_LOGIC_VECTOR  ((bus_size-1) downto 0);
    MEM_Read             : in     STD_LOGIC;	 
    MEM_Write            : in     STD_LOGIC
  );
end MemorySample;

architecture Behavioral of MemorySample is
type ram_type is array (0 to 110-1) of std_logic_vector(bus_size-1 downto 0);
signal tmp_ram: ram_type;
begin
  
  -- Read Part
  process (CLK,MEM_Read)
  begin
    if falling_edge(CLK) then	   
	     if MEM_Read = '1' then
  		    case MEM_ReadAdd is
		      when conv_std_logic_vector(0, bus_size) =>
			     MEM_Data <= "0001000000000010";  -- mov r1,2  00010 00000000010
			   
				when conv_std_logic_vector(1, bus_size) =>
			     MEM_Data <= "0000100100001000";  -- mov r2,r1 00001 0010 0001 000
				
				when conv_std_logic_vector(2, bus_size) =>
			     MEM_Data <= "1101000100000000";  -- out r2    11010 0010 0000 000    
				
			   when conv_std_logic_vector(3, bus_size) =>
			     MEM_Data <= "0101000010010000";  -- add r1,r2 01010 0001 0010 000
				  
				when conv_std_logic_vector(4, bus_size) =>
			     MEM_Data <= "1101000010000000";  -- out r1    11010 0001 0000 000
				  
				when conv_std_logic_vector(5, bus_size) =>
			     MEM_Data <= "0101100010001000";  -- sub r1,r1 01011 0001 0001 000
				
				when conv_std_logic_vector(6, bus_size) =>
			     MEM_Data <= "1101000010000000";  -- out r1    11010 0001 0000 000
				  
				when conv_std_logic_vector(7, bus_size) =>
			     MEM_Data <= "0001000000000101";  -- mov r1,5  00010 00000000101
				  
				when conv_std_logic_vector(8, bus_size) =>
			     MEM_Data <= "0000100110001000";  -- mov r3,r1 00001 0011 0001 000
				
				when conv_std_logic_vector(9, bus_size) =>
			     MEM_Data <= "0101000110010000";  -- add r3,r2 01010 0011 0010 000
				
				when conv_std_logic_vector(10, bus_size) =>
			     MEM_Data <= "1101000010000000";  -- out r1    11010 0001 0000 000
				  
				when conv_std_logic_vector(11, bus_size) =>
			     MEM_Data <= "0011100010000000";  -- not r1    00111 0001 0000 000 (r1 = not r1);
				  
				when conv_std_logic_vector(12, bus_size) =>
			     MEM_Data <= "1101000010000000";  -- out r1    11010 0001 0000 000
				  
				when conv_std_logic_vector(13, bus_size) =>
			     MEM_Data <= "1101000100000000";  -- out r2    11010 0010 0000 000
				
				when conv_std_logic_vector(14, bus_size) =>
			     MEM_Data <= "0100000100000000";  -- inc r2    01000 0010 0000 000
				
				when conv_std_logic_vector(15, bus_size) =>
			     MEM_Data <= "1101000100000000";  -- out r2    11010 0010 0000 000
				
				when conv_std_logic_vector(16, bus_size) =>
			     MEM_Data <= "0100100100000000";  -- dec r2    01001 0010 0000 000
				
				when conv_std_logic_vector(17, bus_size) =>
			     MEM_Data <= "1101000100000000";  -- out r2    11010 0010 0000 000
				  
				when conv_std_logic_vector(18, bus_size) =>
			     MEM_Data <= "0110000100000000";  -- shfl r2   01100 0010 0000 000
				
				when conv_std_logic_vector(19, bus_size) =>
			     MEM_Data <= "1101000100000000";  -- out r2    11010 0010 0000 000
				
				when conv_std_logic_vector(20, bus_size) =>
			     MEM_Data <= "0110100100000000";  -- shfr r2   01101 0010 0000 000
				
				when conv_std_logic_vector(21, bus_size) =>
			     MEM_Data <= "1101000100000000";  -- out r2    11010 0010 0000 000
				  
				when conv_std_logic_vector(22, bus_size) =>
			     MEM_Data <= "0111000100000000";  -- rotr r2    01110 0010 0000 000
				
				when conv_std_logic_vector(23, bus_size) =>
			     MEM_Data <= "1101000100000000";  -- out r2    11010 0010 0000 000
				
				when conv_std_logic_vector(24, bus_size) =>
			     MEM_Data <= "0001000000000010";  -- mov r1,2  00010 00000000010
				
				when conv_std_logic_vector(25, bus_size) =>
			     MEM_Data <= "0001100100001000";  -- ldm r2,r1  00011 0010 0001 000 ( r2 = mem(r1) )
				
				when conv_std_logic_vector(26, bus_size) =>
			     MEM_Data <= "1101000100000000";  -- out r2    11010 0010 0000 000
				
				when conv_std_logic_vector(27, bus_size) =>
			     MEM_Data <= "1101000010000000";  -- out r1    11010 0001 0000 000
				  
				when conv_std_logic_vector(28, bus_size) =>
			     MEM_Data <= "0001000000110010";  -- mov r1,50  00010 00000110010  
				  
				when conv_std_logic_vector(29, bus_size) =>
			     MEM_Data <= "0010000010010000";  -- stm r1,r2  00100 0001 0010 000 ( mem(r1) = r2 ) 
				
				when conv_std_logic_vector(30, bus_size) =>
			     MEM_Data <= "0001000000110010";  -- mov r1,50  00010 00000110010
				
				when conv_std_logic_vector(31, bus_size) =>
			     MEM_Data <= "0001100110001000";  -- ldm r3,r1  00011 0011 0001 000 ( r3 = mem(r1) )
				
				when conv_std_logic_vector(32, bus_size) =>
			     MEM_Data <= "1101000110000000";  -- out r3    11010 0011 0000 000
				
				when conv_std_logic_vector(33, bus_size) =>
			     MEM_Data <= "0001000000100011";  -- mov r1,35  00010 00000100011
				
				when conv_std_logic_vector(34, bus_size) =>
			     MEM_Data <= "0111100010000000";  -- jmp r1  01111 0001 0000 000
				
				when conv_std_logic_vector(35, bus_size) =>
			     MEM_Data <= "1101000010000000";  -- out r1    11010 0001 0000 000
				
				when conv_std_logic_vector(36, bus_size) =>
			     MEM_Data <= "1101000010000000";  -- out r1    11010 0001 0000 000
				
				when conv_std_logic_vector(37, bus_size) =>
			     MEM_Data <= "1110000000000000";  -- nop       11100 0000 0000 000
			   
				when conv_std_logic_vector(38, bus_size) =>
				  MEM_Data <= "1000000000000010";  -- jmpr      10000 1 0000000010  -- Jump back two instruction
				
				when conv_std_logic_vector(39, bus_size) =>
			     MEM_Data <= "1101100000000000";  -- halt      11011 0000 0000 000
				
				when conv_std_logic_vector(40, bus_size) =>
			     MEM_Data <= "1101000110000000";  -- out r3    11010 0011 0000 000
			   
				when conv_std_logic_vector(41, bus_size) =>
			     MEM_Data <= "0001000000101101";  -- mov r1,45 00010 00000101101  
				  
				when conv_std_logic_vector(42, bus_size) =>
			     MEM_Data <= "0000100100001000";  -- mov r2,r1 00001 0010 0001 000
				
				when conv_std_logic_vector(43, bus_size) =>
			     MEM_Data <= "0101100010001000";  -- sub r1,r1 01011 0001 0001 000
				
				when conv_std_logic_vector(44, bus_size) =>
			     MEM_Data <= "1000100100000000";  -- jz  r2    10001 0010 0000 000
				  
				when conv_std_logic_vector(45, bus_size) =>  
				  MEM_Data <= "0001000000101111";  -- mov r1,47 00010 00000101111
            
            when conv_std_logic_vector(46, bus_size) =>
			     MEM_Data <= "1001100010000000";  -- jnz r1    10011 0001 0000000				
				
				when conv_std_logic_vector(47, bus_size) =>
			     MEM_Data <= "1101000010000000";  -- out r1    11010 0001 0000 000
				
				when conv_std_logic_vector(48, bus_size) =>
			     MEM_Data <= "0001000001100100";  -- mov r1,100 00010 00001100100  
				  
				when conv_std_logic_vector(49, bus_size) =>
			     MEM_Data <= "0000111010001000";  -- mov r13,r1 00001 1101 0001 000
				
				when conv_std_logic_vector(50, bus_size) =>
			     MEM_Data <= "0000111010001000";  -- mov r13,r1 00001 1101 0001 000
				
				when conv_std_logic_vector(51, bus_size) =>
			     MEM_Data <= "0001000000000001";  -- mov r1,1 00010 00000000001  
				
				when conv_std_logic_vector(52, bus_size) =>
			     MEM_Data <= "1110100010000000";  -- push r1    11101 0001 0000 000
				  
				when conv_std_logic_vector(53, bus_size) =>
			     MEM_Data <= "0001000000000010";  -- mov r1,2 00010 00000000010  
				
				when conv_std_logic_vector(54, bus_size) =>
			     MEM_Data <= "1110100010000000";  -- push r1    11101 0001 0000 000
				
				when conv_std_logic_vector(55, bus_size) =>
			     MEM_Data <= "0001000000000011";  -- mov r1,3 00010 00000000011
				
				when conv_std_logic_vector(56, bus_size) =>
			     MEM_Data <= "1110100010000000";  -- push r1    11101 0001 0000 000
				  				
				when conv_std_logic_vector(57, bus_size) =>
			     MEM_Data <= "1111000010000000";  -- pop r1    11110 0001 0000000
				
				when conv_std_logic_vector(58, bus_size) =>
			     MEM_Data <= "1101000010000000";  -- out r1    11010 0001 0000 000
				
				when conv_std_logic_vector(59, bus_size) =>
			     MEM_Data <= "1111000010000000";  -- pop r1    11110 0001 0000000
				
				when conv_std_logic_vector(60, bus_size) =>
			     MEM_Data <= "1101000010000000";  -- out r1    11010 0001 0000 000
				  
				when conv_std_logic_vector(61, bus_size) =>
			     MEM_Data <= "1111000010000000";  -- pop r1    11110 0001 0000000
				
				when conv_std_logic_vector(62, bus_size) =>
			     MEM_Data <= "1101000010000000";  -- out r1    11010 0001 0000 000
				
				when conv_std_logic_vector(63, bus_size) =>
			     MEM_Data <= "0001000001010000";  -- mov r1,80  00010 00001010000  
				  
 			   when conv_std_logic_vector(64, bus_size) =>
			     MEM_Data <= "1011100010000000";  -- call r1      10111 0001 0000000	
				
				when conv_std_logic_vector(65, bus_size) =>
			     MEM_Data <= "1101000010000000";  -- out r1    11010 0001 0000 000
				
				when conv_std_logic_vector(66, bus_size) =>
			     MEM_Data <= "1101100000000000";  -- halt      11011 0000 0000 000

            when conv_std_logic_vector(80, bus_size) =>
			     MEM_Data <= "1110000000000000";  -- nop       11100 0000 0000 000
				
				when conv_std_logic_vector(81, bus_size) =>
			     MEM_Data <= "0001011111111110";  -- mov r1,2046  00010 11111111110  
				
				when conv_std_logic_vector(82, bus_size) =>
			     MEM_Data <= "1101000010000000";  -- out r1    11010 0001 0000 000
				
				when conv_std_logic_vector(83, bus_size) =>
			     MEM_Data <= "1100000000000000";  -- ret       11000 0000 0000 000
				
				when others =>
			     MEM_Data <= tmp_ram(conv_integer(MEM_ReadAdd));
		    end case;		  
		  end if;	   
	 end if;
  end process;
  
  -- Write part
  process(CLK, MEM_Write)
  begin
    if falling_edge(CLK) then      
	     if MEM_Write = '1' then
		    tmp_ram(conv_integer(MEM_WriteAdd)) <= MEM_DataIn;
		  end if;	   
	 end if;	
  end process;

end Behavioral;

